package com.icloud.cer.rest;

import java.util.concurrent.atomic.AtomicInteger;

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.icloud.cer.rest.msg.MessageHeader;
import com.icloud.cer.rest.msg.MessageHolder;
import com.icloud.cer.rest.msg.MsgConstants;
import com.icloud.cer.rest.msg.bean.ClientEncyptRequest;
import com.icloud.cer.rest.msg.bean.EncryptResponse;
import com.icloud.cer.rest.msg.bean.HeartbeatResponse;
import com.icloud.cer.rest.test.bean.RegistClientInfo;
import com.icloud.cer.rest.util.MessageSequenceGenerator;

public class ObjectMinaClientHandler extends IoHandlerAdapter {
	private static final Logger log = LoggerFactory.getLogger(ObjectMinaClientHandler.class);
	private final AtomicInteger count = new AtomicInteger(0);
	
	public ObjectMinaClientHandler() {
		
	}
	@Override
	public void sessionOpened(IoSession session) throws Exception {
		log.info("connect server success." + session.getRemoteAddress());
		session.getConfig().setReadBufferSize( 2048 );
		sendRegToServer2(session);
		//定时发送任务
		//new RequestTaskThread().start();
	}

	// 当一个服务端关闭时
	@Override
	public void sessionClosed(IoSession session) {
		log.info(session.getRemoteAddress() + " server Disconnect !");
	}
	
	public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
		cause.printStackTrace();
	}

	// 当服务器发送的消息到达时:
	@Override
	public void messageReceived(IoSession session, Object message) throws Exception {
		MessageHolder hoder = (MessageHolder)message;
		short command = hoder.getCommand();
		long sequence = hoder.getSequence();
		log.info("sessionId:" + session.getId() + ",sequence:" + sequence);
		switch (command) {
		case MsgConstants.SERVER_RES_REG:
			log.info("注册成功 " + command);
			break;
		case MsgConstants.SERVER_REQ_HEARTBEAT:
			log.info("收到服务器心跳请求 " + command);
			sendHeartbeatResponse(session, sequence);
			log.info("响应服务器心跳请求 " + MsgConstants.CLIENT_RES_HEARTBEAT);
			break;
		case MsgConstants.SERVER_SENT_ENCRYPT:
			log.info("收到服务器端加密任务");
			MessageHolder mh = (MessageHolder)message;
			sendEncryptResult(session, sequence);
			log.info("将加密结果返回给服务器端");
			break;
		default:
			log.error("不合法的command");
			break;
		}
		// 发送到服务端
		// session.write(u);
	}

	public void sendRegToServer2(IoSession session) {
		log.info("向服务器发送注册请求");
		MessageHeader header = new MessageHeader();
		header.setSize_(96);
		header.setFlag_(Constants.DEFAULT_CODEC_FLAG);
		header.setType_((short)200);
		MessageHolder bodyHolder = new MessageHolder((short)200);
		bodyHolder.setHead(header);
		RegistClientInfo ri = new RegistClientInfo();
		//long seq = MessageSequenceGenerator.getNextMessageId();
		String id = new String(MinaClientTest.getEncryptorId());
		String name = new String(MinaClientTest.getEncryptorName());
		log.info("id:" + id );
		log.info("name:" + name );
		ri.setEncryptorNameStr(name);
		ri.setEncryptorIdStr(id);
		
		//bodyHolder.setSequence(seq);
		bodyHolder.setValue(ri);
		session.write(bodyHolder);
	}
	
	public String getEncryptorName() {
		StringBuffer name = new StringBuffer();
		for (int i = 0; i < 8; i++) {
			name.append("hz01-001");
		}
		return name.toString();
	}
	
	public String getEncryptorId() {
		StringBuffer id = new StringBuffer();
		for (int i = 0; i < 8; i++) {
			id.append("hz01");
		}
		return id.toString();
	}
	
	public void sendHeartbeatResponse(IoSession session, long sequence) {
		MessageHeader header = new MessageHeader();
		header.setSize_(8);
		header.setFlag_(Constants.DEFAULT_CODEC_FLAG);
		header.setType_((short)152);
		MessageHolder bodyHolder = new MessageHolder((short)152);
		bodyHolder.setHead(header);
		HeartbeatResponse ri = new HeartbeatResponse();
		ri.setSequence(sequence);
		ri.setStatus(1);
		bodyHolder.setSequence(sequence);
		bodyHolder.setValue(ri);
		session.write(bodyHolder);
	}
	
	public void sendEncryptResult(final IoSession session, long sequence) {
		MessageHeader header = new MessageHeader();
		header.setSize_(EncryptResponse.BYTE_COUNT);//564
		header.setFlag_('l');
		header.setType_((short)MsgConstants.CLIENT_RES_ENCRYPT);//102
		
//		long sequence = MessageSequenceGenerator.getNextMessageId();
		EncryptResponse er= new EncryptResponse();
		er.setCertificationStr(getCer2());
		er.setSequence(sequence);
		er.setTaskId(1234l);
		er.setUserIdStr(getUserId2());
		er.setErrorCode(0);
		er.setErrorMsgStr("no error");//error_code: 11007, error_msg:[ERROR] get user pulick key error
		er.setFlag_('l');
		
		MessageHolder holder = new MessageHolder(MsgConstants.CLIENT_REQ_ENCRYPT);
		holder.setHead(header);
		holder.setValue(er);
		holder.setCommand(MsgConstants.CLIENT_REQ_ENCRYPT);
		holder.setSequence(sequence);
		
		try {
			Thread.sleep(1000);
			log.info("sleep 1s");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		session.write(holder);
	}
	
	public void mockHeartBeat(final IoSession session) {
		new Thread() {
			public void run() {
				while (true) {
					try {
						Thread.sleep(10000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					session.write(getEnReq());
//					IoBuffer buffer = IoBuffer.allocate(8);
//					buffer.setAutoExpand(false);
//					buffer.putInt(2);
//					buffer.putShort((short) 152);
//					buffer.putChar('b');
				}
			}
		}.start();
	}
	
	public MessageHolder getEnReq() {
		MessageHeader header = new MessageHeader();
		header.setSize_(8 + ClientEncyptRequest.BYTE_COUNT);
		header.setFlag_(Constants.DEFAULT_CODEC_FLAG);
		header.setType_((short)100);
		
		long sequence = MessageSequenceGenerator.getNextMessageId();
		ClientEncyptRequest clientEr = new ClientEncyptRequest();
		clientEr.setTaskCount(1);
		MessageHolder holder = new MessageHolder(MsgConstants.CLIENT_REQ_ENCRYPT);
		holder.setHead(header);
		holder.setValue(clientEr);
		holder.setCommand(MsgConstants.CLIENT_REQ_ENCRYPT);
		holder.setSequence(sequence);
		return holder;
	}
	
	public byte[] int2byte(int res) {
		byte[] targets = new byte[4];

		targets[0] = (byte) (res & 0xff);// 最低位
		targets[1] = (byte) ((res >> 8) & 0xff);// 次低位
		targets[2] = (byte) ((res >> 16) & 0xff);// 次高位
		targets[3] = (byte) (res >>> 24);// 最高位,无符号右移。
		return targets;
	}
	
	public String getUserId() {
		StringBuffer userId = new StringBuffer();
		for (int i = 0; i < 8; i++) {
			userId.append("abcd");
		}
		return userId.toString();
	}
	public String getUserId2() {
		StringBuffer userId = new StringBuffer();
		for (int i = 0; i < 8; i++) {
			userId.append("efef");
		}
		return userId.toString();
	}
	
	public String getCer() {
		StringBuffer cer = new StringBuffer();
		for (int i = 0; i < 32; i++) {
			cer.append("abcd1234");
		}
		return cer.toString();
	}
	
	public String getCer2() {
		StringBuffer cer = new StringBuffer();
		for (int i = 0; i < 32; i++) {
			cer.append("efef1212");
		}
		return cer.toString();
	}
	
	class RequestTaskThread extends Thread {
		public RequestTaskThread() {
			setName("Task Thread");
			this.setDaemon(true);
		}

		public void run() {
			log.info("Request Task Thread run......");
			while (true) {
				try {
					Thread.sleep(12000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				IoSession session = MinaClientTest.getSession();
				if(session.isConnected()) {
					log.info("Request task." + count.incrementAndGet());
					MinaClientTest.getSession().write(getEnReq());
				} else {
					log.warn("session closed. client exit!");
					break;
					
				}
			}
			log.info("Request Task Thread stoped......");
		}
	}
}
